<template>
  <el-dialog
    v-model="dialogVisible"
    :title="`${dialogProps.title}`"
    :align-center="true"
    :destroy-on-close="true"
    width="780px"
    draggable
  >
    <el-form
      ref="ruleFormRef"
      label-width="100px"
      label-suffix=" :"
      :rules="rules"
      :disabled="dialogProps.isView"
      :model="dialogProps.rowData"
      :hide-required-asterisk="dialogProps.isView"
    >
      <el-tabs type="card" class="demo-tabs">
        <el-tab-pane v-for="(module, index) in dialogProps.authTree" :key="index">
          <template #label>
            <span class="custom-tabs-label">
              <el-icon v-if="module.icon_type == 1">
                <component :is="module.icon_name ? module.icon_name : 'Menu'"></component>
              </el-icon>
              <i v-if="module.icon_type == 2" class="el-icon iconfont" :class="module.icon_name" />
              <span>{{ module.title }}</span>
            </span>
          </template>
          <template v-if="module.type === 1 && module.children && module.children.length > 0">
            <el-card v-for="(cate, idx) in module.children" :key="idx" class="box-card menu-card">
              <template #header>
                <div class="card-header">
                  <span>{{ cate.title }}</span>
                </div>
              </template>
              <template v-if="cate.type === 2 && cate.children && cate.children.length > 0">
                <AuthItem
                  v-for="(menu, i) in cate.children"
                  :key="i"
                  :auth-ids="dialogProps.rowData.auth_ids"
                  :item="menu"
                  @change="handleChange"
                  class="menu"
                />
              </template>
              <template v-else-if="cate.type === 3">
                <AuthItem :auth-ids="dialogProps.rowData.auth_ids" :item="cate" @change="handleChange" class="menu" />
              </template>
            </el-card>
          </template>
          <template v-else-if="module.type === 2 && module.children && module.children.length > 0">
            <el-card class="box-card menu-card">
              <template #header>
                <div class="card-header">
                  <span>{{ module.title }}</span>
                </div>
              </template>
              <AuthItem
                v-for="(menu, idx) in module.children"
                :key="idx"
                :auth-ids="dialogProps.rowData.auth_ids"
                :item="menu"
                @change="handleChange"
                class="menu"
              />
            </el-card>
          </template>
          <template v-else>
            <el-card class="box-card menu-card">
              <template #header>
                <div class="card-header">
                  <span>{{ module.title }}</span>
                </div>
              </template>
              <AuthItem :auth-ids="dialogProps.rowData.auth_ids" :item="module" @change="handleChange" class="menu" />
            </el-card>
          </template>
        </el-tab-pane>
      </el-tabs>
    </el-form>
    <template #footer>
      <el-button @click="dialogVisible = false">取消</el-button>
      <el-button type="primary" v-show="!dialogProps.isView" @click="handleSubmit">确定</el-button>
    </template>
  </el-dialog>
</template>

<script setup lang="ts" name="RoleDialog">
import { ref, reactive } from "vue";
import { ElMessage, FormInstance } from "element-plus";
import AuthItem from "@/views/system/role/AuthItem.vue";
import {Menu, RoleInfo} from "@/interface/api";
import { authListApi } from "@/api/modules/role";

const rules = reactive({
  authIds: [{ required: true, message: "请选择角色权限" }]
});

interface DialogProps {
  title: string;
  isView: boolean;
  authTree: any[];
  rowData: RoleInfo;
  api?: (params: any) => Promise<any>;
  getTableList?: () => Promise<any>;
}

// dialog框状态
const dialogVisible = ref(false);
const dialogProps = ref<DialogProps>({
  title: "",
  isView: false,
  authTree: [],
  rowData: {
    id: 0,
    name: '',
    is_admin: 0,
    level: 0,
    status: 0,
    auth_ids: []
  }
});

// 接收父组件传过来的参数
const acceptParams = (params: DialogProps): void => {
  dialogProps.value = params;
  dialogVisible.value = true;
  dialogProps.value.rowData.auth_ids = [];
  authListApi(dialogProps.value.rowData.id).then(res => {
    const data = res.data as Menu[];
    data.forEach(item => {
      dialogProps.value.rowData.auth_ids.push(item.id);
    });
  });
};

const handleChange = (checked: boolean, menu: any, action?: any) => {
  let children = [];
  if (menu.type === 3 && menu.children && menu.children.length > 0) {
    children = menu.children;
  }
  if (checked) {
    handleChecked(menu, action, children);
  } else {
    handleCheckCancel(menu, action, children);
  }
};

const isChecked = (id: number) => {
  return dialogProps.value.rowData.auth_ids.indexOf(id);
};

const handleChecked = (menu: any, action: any, children: any[]) => {
  if (isChecked(menu.id) == -1) {
    dialogProps.value.rowData.auth_ids.push(menu.id);
  }
  if (action) {
    if (isChecked(action.id) == -1) {
      dialogProps.value.rowData.auth_ids.push(action.id);
    }
  } else {
    children.forEach((child: Menu) => {
      if (isChecked(child.id) == -1) {
        dialogProps.value.rowData.auth_ids.push(child.id);
      }
    });
  }
};

const handleCheckCancel = (menu: any, action: any, children: any[]) => {
  if (action) {
    const index = isChecked(action.id);
    if (index > -1) {
      dialogProps.value.rowData.auth_ids.splice(index, 1);
    }
    let exists = children.some((child: Menu) => dialogProps.value.rowData.auth_ids.indexOf(child.id) > -1);
    if (!exists) {
      const idx = isChecked(menu.id);
      if (idx > -1) {
        dialogProps.value.rowData.auth_ids.splice(idx, 1);
      }
    }
  } else {
    const index = isChecked(menu.id);
    if (index > -1) {
      dialogProps.value.rowData.auth_ids.splice(index, 1);
    }
    children.forEach((child: Menu) => {
      let idx = isChecked(child.id);
      if (idx > -1) {
        dialogProps.value.rowData.auth_ids.splice(idx, 1);
      }
    });
  }
};

// 提交数据（新增/编辑）
const ruleFormRef = ref<FormInstance>();
const handleSubmit = () => {
  ruleFormRef.value!.validate(async valid => {
    if (!valid) return;
    try {
      await dialogProps.value.api!({role_id: dialogProps.value.rowData.id, auth_ids: dialogProps.value.rowData.auth_ids});
      ElMessage.success({ message: `${dialogProps.value.title}成功！` });
      if (dialogProps.value.getTableList) {
        await dialogProps.value.getTableList();
      }
      dialogVisible.value = false;
    } catch (error) {
      console.log(error);
    }
  });
};

defineExpose({
  acceptParams
});
</script>

<style lang="scss" scoped>
:deep(.card-header) {
  display: flex;
  justify-content: space-between;
}
:deep(.custom-tabs-label) {
  display: flex;
  align-items: center;
  .el-icon {
    margin-right: 2px;
  }
}
.menu-card {
  margin-bottom: 15px;
  &:last-child {
    margin-bottom: 0;
  }
}
:deep(.card-header) {
  font-weight: bold;
  color: var(--el-color-primary);
}
.menu {
  margin-bottom: 10px;
  &:last-child {
    margin-bottom: 0;
  }
}
</style>
